package hu.bme.mit.mdsd.service.generator;

import java.util.Arrays;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.xbase.lib.BooleanExtensions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.IteratorExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import system.HttpMethodType;
import system.Method;
import system.NamedClass;
import system.Parameter;
import system.Platform;
import system.RestMethod;
import system.RestParameter;
import system.RestService;
import system.Service;
import system.Type;
import system.Visibility;

@SuppressWarnings("all")
public class ServiceModelGenerator implements IGenerator {
  public void doGenerate(final Resource input, final IFileSystemAccess fsa) {
    TreeIterator<EObject> _allContents = input.getAllContents();
    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
    Iterable<system.System> _filter = IterableExtensions.<system.System>filter(_iterable, system.System.class);
    for (final system.System p : _filter) {
      Platform _targetPlatform = p.getTargetPlatform();
      boolean _operator_equals = ObjectExtensions.operator_equals(_targetPlatform, Platform.OS_GI);
      if (_operator_equals) {
        TreeIterator<EObject> _eAllContents = p.eAllContents();
        Iterable<EObject> _iterable_1 = IteratorExtensions.<EObject>toIterable(_eAllContents);
        Iterable<Service> _filter_1 = IterableExtensions.<Service>filter(_iterable_1, system.Service.class);
        for (final Service e : _filter_1) {
          this.compile(e, fsa, p);
        }
      }
    }
  }
  
  protected void _compile(final Service e, final IFileSystemAccess fsa, final system.System s) {
    String _name = e.getName();
    String _operator_plus = StringExtensions.operator_plus("I", _name);
    String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ".java");
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("package ");
    String _packageName = s.getPackageName();
    _builder.append(_packageName, "");
    _builder.append(".managers;");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("import hu.bme.mit.inf.expendables.entities.*;");
    _builder.newLine();
    _builder.newLine();
    _builder.append("public interface I");
    String _name_1 = e.getName();
    _builder.append(_name_1, "");
    _builder.append(" {");
    _builder.newLineIfNotEmpty();
    {
      EList<Method> _methods = e.getMethods();
      for(final Method m : _methods) {
        _builder.append("\t");
        CharSequence _compile = this.compile(m);
        _builder.append(_compile, "	");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("}");
    _builder.newLine();
    fsa.generateFile(_operator_plus_1, _builder);
  }
  
  protected void _compile(final RestService e, final IFileSystemAccess fsa, final system.System s) {
    String _name = e.getName();
    String _operator_plus = StringExtensions.operator_plus("I", _name);
    String _operator_plus_1 = StringExtensions.operator_plus(_operator_plus, ".java");
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("package ");
    String _packageName = s.getPackageName();
    _builder.append(_packageName, "");
    _builder.append(".restservices;");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("import javax.ws.rs.*;");
    _builder.newLine();
    _builder.append("import javax.ws.rs.core.*;");
    _builder.newLine();
    _builder.newLine();
    _builder.append("import com.sun.jersey.multipart.FormDataParam;");
    _builder.newLine();
    _builder.newLine();
    {
      boolean _operator_and = false;
      String _path = e.getPath();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_path, null);
      if (!_operator_notEquals) {
        _operator_and = false;
      } else {
        String _path_1 = e.getPath();
        boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_path_1, "");
        _operator_and = BooleanExtensions.operator_and(_operator_notEquals, _operator_notEquals_1);
      }
      if (_operator_and) {
        _builder.append("@Path(\"");
        String _path_2 = e.getPath();
        _builder.append(_path_2, "");
        _builder.append("\")");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("public interface I");
    String _name_1 = e.getName();
    _builder.append(_name_1, "");
    _builder.append(" {");
    _builder.newLineIfNotEmpty();
    {
      EList<Method> _methods = e.getMethods();
      for(final Method m : _methods) {
        _builder.append("\t");
        CharSequence _compile = this.compile(m);
        _builder.append(_compile, "	");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("}");
    _builder.newLine();
    fsa.generateFile(_operator_plus_1, "SRCGENREST", _builder);
  }
  
  protected CharSequence _compile(final Method m) {
    StringConcatenation _builder = new StringConcatenation();
    Visibility _visibility = m.getVisibility();
    _builder.append(_visibility, "");
    _builder.append(" ");
    Type _returnType = m.getReturnType();
    String _name = _returnType.getName();
    _builder.append(_name, "");
    _builder.append(" ");
    String _name_1 = m.getName();
    _builder.append(_name_1, "");
    _builder.append("(");
    {
      EList<Parameter> _parameters = m.getParameters();
      boolean _hasElements = false;
      for(final Parameter p : _parameters) {
        if (!_hasElements) {
          _hasElements = true;
        } else {
          _builder.appendImmediate(", ", "");
        }
        CharSequence _compile = this.compile(p);
        _builder.append(_compile, "");
      }
    }
    _builder.append(");");
    _builder.newLineIfNotEmpty();
    return _builder;
  }
  
  protected CharSequence _compile(final RestMethod m) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.newLine();
    _builder.append("@");
    HttpMethodType _methodType = m.getMethodType();
    _builder.append(_methodType, "");
    _builder.newLineIfNotEmpty();
    {
      boolean _operator_and = false;
      String _path = m.getPath();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_path, null);
      if (!_operator_notEquals) {
        _operator_and = false;
      } else {
        String _path_1 = m.getPath();
        boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_path_1, "");
        _operator_and = BooleanExtensions.operator_and(_operator_notEquals, _operator_notEquals_1);
      }
      if (_operator_and) {
        _builder.append("@Path(\"");
        String _path_2 = m.getPath();
        _builder.append(_path_2, "");
        _builder.append("\")");
        _builder.newLineIfNotEmpty();
      }
    }
    {
      boolean _operator_and_1 = false;
      String _consumes = m.getConsumes();
      boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_consumes, null);
      if (!_operator_notEquals_2) {
        _operator_and_1 = false;
      } else {
        String _consumes_1 = m.getConsumes();
        boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_consumes_1, "");
        _operator_and_1 = BooleanExtensions.operator_and(_operator_notEquals_2, _operator_notEquals_3);
      }
      if (_operator_and_1) {
        _builder.append("@Consumes(");
        String _consumes_2 = m.getConsumes();
        _builder.append(_consumes_2, "");
        _builder.append(")");
        _builder.newLineIfNotEmpty();
      }
    }
    {
      boolean _operator_and_2 = false;
      String _produces = m.getProduces();
      boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(_produces, null);
      if (!_operator_notEquals_4) {
        _operator_and_2 = false;
      } else {
        String _produces_1 = m.getProduces();
        boolean _operator_notEquals_5 = ObjectExtensions.operator_notEquals(_produces_1, "");
        _operator_and_2 = BooleanExtensions.operator_and(_operator_notEquals_4, _operator_notEquals_5);
      }
      if (_operator_and_2) {
        _builder.append("@Produces(");
        String _produces_2 = m.getProduces();
        _builder.append(_produces_2, "");
        _builder.append(")");
        _builder.newLineIfNotEmpty();
      }
    }
    Visibility _visibility = m.getVisibility();
    _builder.append(_visibility, "");
    _builder.append(" ");
    Type _returnType = m.getReturnType();
    String _name = _returnType.getName();
    _builder.append(_name, "");
    _builder.append(" ");
    String _name_1 = m.getName();
    _builder.append(_name_1, "");
    _builder.append("(");
    {
      EList<Parameter> _parameters = m.getParameters();
      boolean _hasElements = false;
      for(final Parameter p : _parameters) {
        if (!_hasElements) {
          _hasElements = true;
        } else {
          _builder.appendImmediate(", ", "");
        }
        CharSequence _compile = this.compile(p);
        _builder.append(_compile, "");
      }
    }
    _builder.append(");");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    return _builder;
  }
  
  protected CharSequence _compile(final Parameter p) {
    StringConcatenation _builder = new StringConcatenation();
    Type _type = p.getType();
    String _name = _type.getName();
    _builder.append(_name, "");
    _builder.append(" ");
    String _name_1 = p.getName();
    _builder.append(_name_1, "");
    return _builder;
  }
  
  protected CharSequence _compile(final RestParameter p) {
    StringConcatenation _builder = new StringConcatenation();
    {
      boolean _operator_and = false;
      String _pathParameter = p.getPathParameter();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_pathParameter, null);
      if (!_operator_notEquals) {
        _operator_and = false;
      } else {
        String _pathParameter_1 = p.getPathParameter();
        boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_pathParameter_1, "");
        _operator_and = BooleanExtensions.operator_and(_operator_notEquals, _operator_notEquals_1);
      }
      if (_operator_and) {
        _builder.append("@PathParam(\"");
        String _pathParameter_2 = p.getPathParameter();
        _builder.append(_pathParameter_2, "");
        _builder.append("\") ");
      }
    }
    {
      boolean _operator_and_1 = false;
      String _queryParameter = p.getQueryParameter();
      boolean _operator_notEquals_2 = ObjectExtensions.operator_notEquals(_queryParameter, null);
      if (!_operator_notEquals_2) {
        _operator_and_1 = false;
      } else {
        String _queryParameter_1 = p.getQueryParameter();
        boolean _operator_notEquals_3 = ObjectExtensions.operator_notEquals(_queryParameter_1, "");
        _operator_and_1 = BooleanExtensions.operator_and(_operator_notEquals_2, _operator_notEquals_3);
      }
      if (_operator_and_1) {
        _builder.append("@QueryParam(\"");
        String _queryParameter_2 = p.getQueryParameter();
        _builder.append(_queryParameter_2, "");
        _builder.append("\") ");
      }
    }
    {
      boolean _operator_and_2 = false;
      String _formParameter = p.getFormParameter();
      boolean _operator_notEquals_4 = ObjectExtensions.operator_notEquals(_formParameter, null);
      if (!_operator_notEquals_4) {
        _operator_and_2 = false;
      } else {
        String _formParameter_1 = p.getFormParameter();
        boolean _operator_notEquals_5 = ObjectExtensions.operator_notEquals(_formParameter_1, "");
        _operator_and_2 = BooleanExtensions.operator_and(_operator_notEquals_4, _operator_notEquals_5);
      }
      if (_operator_and_2) {
        _builder.append("@FormParam(\"");
        String _formParameter_2 = p.getFormParameter();
        _builder.append(_formParameter_2, "");
        _builder.append("\") ");
      }
    }
    {
      boolean _operator_and_3 = false;
      String _formDataParameter = p.getFormDataParameter();
      boolean _operator_notEquals_6 = ObjectExtensions.operator_notEquals(_formDataParameter, null);
      if (!_operator_notEquals_6) {
        _operator_and_3 = false;
      } else {
        String _formDataParameter_1 = p.getFormDataParameter();
        boolean _operator_notEquals_7 = ObjectExtensions.operator_notEquals(_formDataParameter_1, "");
        _operator_and_3 = BooleanExtensions.operator_and(_operator_notEquals_6, _operator_notEquals_7);
      }
      if (_operator_and_3) {
        _builder.append("@FormDataParam(\"");
        String _formDataParameter_2 = p.getFormDataParameter();
        _builder.append(_formDataParameter_2, "");
        _builder.append("\") ");
      }
    }
    Type _type = p.getType();
    String _name = _type.getName();
    _builder.append(_name, "");
    _builder.append(" ");
    String _name_1 = p.getName();
    _builder.append(_name_1, "");
    return _builder;
  }
  
  public void compile(final Service e, final IFileSystemAccess fsa, final system.System s) {
    if (e instanceof RestService) {
      _compile((RestService)e, fsa, s);
    } else if (e != null) {
      _compile(e, fsa, s);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(e, fsa, s).toString());
    }
  }
  
  public CharSequence compile(final NamedClass m) {
    if (m instanceof RestMethod) {
      return _compile((RestMethod)m);
    } else if (m instanceof RestParameter) {
      return _compile((RestParameter)m);
    } else if (m instanceof Method) {
      return _compile((Method)m);
    } else if (m instanceof Parameter) {
      return _compile((Parameter)m);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(m).toString());
    }
  }
}
